const imModel = require('@/models/im.model')
const userModel = require('@/models/user.model')
const JsonResult = require('@/utils/httpResponse.unit')
const { newRandomId, dateFormat } = require('@/utils/common.util')
const clients = require('@/websocket')
const { sendMessage } = require('@/websocket/chat')

class ImController {
  /**
   * 当前聊天人员列表查询
   * @param {*} req
   * @param {*} response
   */
  async findChatPersonList (req, response) {
    const sessionUserId = req.sessionuser.id
    try {
      const data = await imModel.findChatPersonList(sessionUserId)
      JsonResult.success({
        req,
        response,
        data,
        message: '查询成功'
      })
    } catch (error) {
      JsonResult.fail({ req, response, error, message: '查询失败' })
    }
  }

  /**
   * 与指定用户的聊天记录查询
   * @param {*} req
   * @param {*} response
   */
  async findChatRecordPage (req, response) {
    const fromId = req.sessionuser.id
    const { toId, pageNo = 1, pageSize = 20 } = req.body
    try {
      const data = await imModel.findPage(fromId, toId, pageNo, pageSize)
      JsonResult.success({
        req,
        response,
        data,
        message: '查询成功'
      })
    } catch (error) {
      JsonResult.fail({ req, response, error, message: '查询失败' })
    }
  }

  /**
   * 删除预指定人的所有聊天记录
   * @param {*} req
   * @param {*} response
   */
  async deleteChatPerson (req, response) {
    const fromId = req.sessionuser.id
    const toId = req.body.toId
    try {
      const data = await imModel.deleteChatPersonIm(fromId, toId)
      JsonResult.success({
        req,
        response,
        data,
        message: '删除成功'
      })
    } catch (error) {
      JsonResult.fail({ req, response, error, message: '删除失败' })
    }
  }

  /**
   * 聊天记录删除
   * @param {*} req
   * @param {*} response
   */
  async deleteIm (req, response) {
    const userId = req.sessionuser.id
    const imId = req.body.imId
    try {
      await imModel.deleteSingleIm(imId, userId)
      JsonResult.success({
        req,
        response,
        message: '删除成功'
      })
    } catch (error) {
      JsonResult.fail({ req, response, error, message: '删除失败' })
    }
  }

  /**
   * 批量已读消息
   * @param {*} req
   * @param {*} response
   */
  async batchReadMessage (req, response) {
    const userId = req.sessionuser.id
    const { fromId, sendTimeStamp } = req.body
    try {
      await imModel.batchReadMessage(userId, fromId, sendTimeStamp)
      JsonResult.success({
        req,
        response
      })
    } catch (error) {
      JsonResult.success({
        req,
        response
      })
    }
  }

  /**
   * 置顶聊天
   * @param {*} req
   * @param {*} response
   */
  async topIm (req, response) {
    const fromId = req.sessionuser.id
    const toId = req.query.toId
    try {
      const existToUser = await userModel.findOne({ id: toId })
      if (!existToUser) {
        return JsonResult.fail({ req, response, message: '待置顶的聊天用户不存在' })
      }
      await imModel.topIm(fromId, toId)
      JsonResult.success({
        req,
        response,
        message: '置顶成功'
      })
    } catch (error) {
      JsonResult.fail({ req, response, error, message: '置顶失败' })
    }
  }

  /**
   * 取消置顶
   * @param {*} req
   * @param {*} response
   */
  async resetTopIm (req, response) {
    const fromId = req.sessionuser.id
    const toId = req.query.toId
    try {
      await imModel.resetTopIm(fromId, toId)
      JsonResult.success({
        req,
        response,
        message: '取消置顶成功'
      })
    } catch (error) {
      JsonResult.fail({ req, response, error, message: '取消置顶失败' })
    }
  }

  /**
   * 撤回聊天
   * @param {*} req
   * @param {*} response
   */
  async revocationIm (req, response) {
    const imId = req.query.imId
    const userId = req.sessionuser.id
    try {
      const targetIm = await imModel.findOneById(imId)
      if (!targetIm) {
        return JsonResult.fail({ req, response, message: '聊天记录不存在' })
      }
      if (targetIm.fromId !== userId) {
        return JsonResult.httpStatus(req, response, 403, {
          message: 'No permission to revocate im',
          code: '9999'
        })
      }
      await imModel.delete(imId)
      JsonResult.success({
        req,
        response,
        message: '撤回成功'
      })
      this.createRevocateSysMessage(targetIm.fromId, targetIm.toId, imId)
    } catch (error) {
      JsonResult.fail({ req, response, error, message: '撤回失败' })
    }
  }

  async createRevocateSysMessage (fromId, toId, deleteImId) {
    const id = newRandomId()
    const sendTime = dateFormat(new Date())
    const sendTimeStamp = new Date().getTime()
    const params = {
      id,
      fromId,
      toId,
      content: '消息已被撤回',
      sys: '1',
      sendTime,
      sendTimeStamp,
      receiveTime: sendTime,
      im: true,
      deleteImId
    }
    imModel.create(params)
    for (let i = 0; i < clients[fromId]?.length; i++) {
      sendMessage(params, clients[fromId][i])
    }
    for (let i = 0; i < clients[toId]?.length; i++) {
      sendMessage(params, clients[toId][i])
    }
  }
}

module.exports = new ImController()
